#pragma once

#include "Standard.h"

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <Summary>	CriticalSection  </Summary>
/// 
/// <purpose>	Wrapper class for a windows CRITICAL_SECTION	</purpose>
////////////////////////////////////////////////////////////////////////////////////////////////////

class CriticalSection
{
protected:

	/// <Summary> The CRITICAL_SECTION for this object </Summary>
    mutable CRITICAL_SECTION cs;

private:

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Makes copy and assignment unavailable to this class </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	DISALLOW_COPY_AND_ASSIGN(CriticalSection)

public:

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Constructor </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	CriticalSection()
	{
		InitializeCriticalSection( &cs );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Destructor </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	~CriticalSection()
	{
		DeleteCriticalSection( &cs );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Lock </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	void Lock()
    {
		EnterCriticalSection( &cs );
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Unlock </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	void Unlock()
    {
		LeaveCriticalSection( &cs );
	}
};

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <Summary>	ScopedCriticalSection  </Summary>
/// 
/// <purpose>	
///		Wrapper class that allows for easy manipulation of locks in a scoped space	
/// </purpose>
////////////////////////////////////////////////////////////////////////////////////////////////////

class ScopedCriticalSection
{
private:

	/// <Summary> Reference to the critical section used </Summary>
	CriticalSection& cs;

private:

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Makes copy and assignment unavailable to this class </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	DISALLOW_COPY_AND_ASSIGN(ScopedCriticalSection)

public:

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Constructor </Summary>
	///
	/// <Param name="_cs">	The critical section to be used in this scope </Param>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	ScopedCriticalSection(CriticalSection& _cs) : cs(_cs)
	{
		cs.Lock();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Destructor </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	~ScopedCriticalSection()
	{
		cs.Unlock();
	}
};